﻿using NetSDKCS;
using PSDLib.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using CaseManagerLibrary.Models;

namespace PSDClient.Service
{

    public class DH_EVS_Downloader : IDownloader
    {
        public IntPtr m_LoginID = IntPtr.Zero;
        public NET_DEVICEINFO_Ex m_DeviceInfo;
        private IntPtr m_DownloadID = IntPtr.Zero;

        private fTimeDownLoadPosCallBack m_DownloadPosCallBack;
        public string Id { get; set; }
        public string ServerIP { get; set; }
        public ushort ServerPort { get; set; }
        public string UserId { get; set; }
        public string Password { get; set; }

        public dl_files FileInfo { get; set; }

        public event UpdateDownloadProgressEventHandler UpdateDownloadProgress;
        public event FileDownloadSuccessEventHandler FileDownloadSuccess;
        public event FileDownloadFailedEventHandler FileDownloadFail;


        public HResult Download(dl_files file)
        {
            HResult result = new HResult() { success = false };

            FileInfo = file;
            FileInfo.dl_progress = 0;

            try
            {
                //if (Login() > 0)
                //{
                DateTime startTime = file.video_start_time;
                DateTime endTime = file.video_end_time;

                if (startTime == endTime)
                {
                    result.message = "The start time is the same ad the end time(开始时间与结束时间相同)!";
                    FileInfo.error_log = result.message;
                    FinishDownload(false);
                    return result;
                }
                if (startTime > endTime)
                {
                    result.message = "The start time is greater than the end time(开始时间大于结束时间)!";
                    FileInfo.error_log = result.message;
                    FinishDownload(false);
                    return result;
                }
                //set stream type 设置码流类型
                EM_STREAM_TYPE streamType = (EM_STREAM_TYPE)(file.stream_type + 1);
                IntPtr pStream = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(int)));
                Marshal.StructureToPtr((int)streamType, pStream, true);
                DaHuaNetClient.SetDeviceMode(m_LoginID, EM_USEDEV_MODE.RECORD_STREAM_TYPE, pStream);

                if (!Directory.Exists(file.file_path))
                {
                    Directory.CreateDirectory(file.file_path);
                }

                string fileName = Path.Combine(file.file_path, file.file_name);

                m_DownloadPosCallBack = new fTimeDownLoadPosCallBack(DownLoadPosCallBack);

                FileInfo.dl_start_time = DateTime.Now;
                //FileInfo.file_path = fileName;

                System.IO.File.Delete(fileName);

                m_DownloadID = DaHuaNetClient.DownloadByTime(m_LoginID, Convert.ToInt32(file.channel_id), EM_QUERY_RECORD_TYPE.ALL, startTime, endTime, fileName, m_DownloadPosCallBack, IntPtr.Zero, null, IntPtr.Zero, IntPtr.Zero);
                if (IntPtr.Zero == m_DownloadID)
                {
                    result.success = false;
                    result.message = DaHuaNetClient.GetLastError();
                    FileInfo.error_log = result.message;
                    FileInfo.state = 2;
                    FinishDownload(false);
                }
                else
                {
                    result.success = true;
                }
            }
            catch (Exception ex)
            {
                result.success = false;
                result.message = ex.Message;
                FileInfo.error_log = ex.Message;
                FileInfo.state = 2;
                FinishDownload(false);
            }

            return result;
        }


        private void DownLoadPosCallBack(IntPtr lPlayHandle, uint dwTotalSize, uint dwDownLoadSize, int index, NET_RECORDFILE_INFO recordfileinfo, IntPtr dwUser)
        {
            try
            {
               //Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " dwTotalSize=" + dwTotalSize + " dwDownLoadSize=" + dwDownLoadSize);
                if (lPlayHandle == m_DownloadID)
                {
                    if ((int)dwDownLoadSize == -1)
                    {
                        FileInfo.dl_progress = 100;                       
                        FinishDownload(true);
                    }
                    else if ((int)dwDownLoadSize == -2)
                    {
                        FileInfo.error_log = DaHuaNetClient.GetLastError();
                        FinishDownload(false);
                    }
                    else
                    {
                        FileInfo.file_size = (Int64)dwDownLoadSize * 1024;

                        int diff = Convert.ToInt32((DateTime.Now - FileInfo.dl_start_time.Value).TotalSeconds);

                        if (dwDownLoadSize >= dwTotalSize)
                        {
                            FileInfo.dl_progress = 100;
                            UpdateDownloadProgress?.Invoke(FileInfo, diff);
                        }
                        else
                        {
                            if (diff > 0)
                            {
                                FileInfo.dl_speed = FileInfo.file_size / diff;
                            }
                            FileInfo.dl_progress = (int)(dwDownLoadSize * 100 / dwTotalSize);
                            UpdateDownloadProgress?.Invoke(FileInfo, diff);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                string s = ex.Message;
            }
        }

        public HResult Stop()
        {
            HResult result = new HResult();
            result.success = DaHuaNetClient.StopDownload(m_DownloadID);

            if (!result.success)
            {
                result.message = DaHuaNetClient.GetLastError();
            }

            return result;
        }

        private void FinishDownload(bool success)
        {
            FileInfo.dl_end_time = DateTime.Now;
            FileInfo.state = (success ? 1 : 2);

            System.Threading.Thread.Sleep(1000 * 2);

            //Logout();

            if (success)
            {
                FileDownloadSuccess(FileInfo);
            }
            else
            {
                FileDownloadFail(FileInfo);
            }
        }

        //private int Login()
        //{
        //    m_DeviceInfo = new NET_DEVICEINFO_Ex();

        //    m_LoginID = NETClient.LoginWithHighLevelSecurity(this.ServerIP, this.ServerPort, this.UserId, this.Password, EM_LOGIN_SPAC_CAP_TYPE.TCP, IntPtr.Zero, ref m_DeviceInfo);

        //    if (IntPtr.Zero == m_LoginID)
        //    {
        //        FileInfo.error_log = NETClient.GetLastError();
        //    }

        //    return m_LoginID.ToInt32();
        //}

        //private void Logout()
        //{
        //    try
        //    {
        //        bool result = NETClient.Logout(m_LoginID);
        //    }
        //    catch { }
        //}
    }
}
